package com.wjs.examfrog.gateway.loadbalance;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.server.ServerWebExchange;

import java.net.InetSocketAddress;
import java.util.List;
import java.util.Random;
import java.util.SortedMap;
import java.util.TreeMap;

@Slf4j
public class ConsistencyHash {
    //存放虚拟节点的treeMap，value是真实节点的下标
    private SortedMap<Integer,Integer> sortedMap;

    //存放真实节点
    private List<ServiceInstance> serviceInstances;

    //存放每个节点拥有的虚拟节点个数
    private final int NODES_SIZE;

    public ConsistencyHash(DiscoveryClient discoveryClient, int NODES_SIZE) {
        this.sortedMap = new TreeMap<>();
        this.serviceInstances = discoveryClient.getInstances("ef-server-other");
        this.NODES_SIZE = NODES_SIZE;
        int n = serviceInstances.size();
        Random random = new Random();
        for (int i = 0;i < n;i++) {
            //ServiceInstance instance = serviceInstances.get(i);
            //String host = instance.getHost();
            String host = random.nextInt(2147483644)+"";
            sortedMap.put(host.hashCode(),i);
            for (int j = 0; j < NODES_SIZE-1; j++) {
                int hash = (host + j).hashCode();
                sortedMap.put(hash,i);
                log.info("第{}个服务器：hash值为：{}",(i+1),hash);
            }
        }
    }

    public ServiceInstance choose(ServerWebExchange exchange){
        //使用IP地址做负载均衡
        /*InetSocketAddress host = exchange.getRequest().getHeaders().getHost();
        String hostAddress;
        if (StringUtils.equals(host.getHostName(), "localhost")) {
            hostAddress = "127.0.0.1";
        } else {
            hostAddress = host.getAddress().getHostAddress();
        }*/
        List<String> params = exchange.getRequest().getQueryParams().get("key");
        SortedMap<Integer, Integer> tailMap = sortedMap.tailMap(Integer.parseInt(params.get(0)));
        int index;
        if(tailMap.isEmpty()){
            index = sortedMap.get(sortedMap.firstKey());
        } else {
            index = tailMap.get(tailMap.firstKey());
        }
        log.info("总共：{}个服务器，当前使用第{}个",serviceInstances.size(),(index+1));
        return serviceInstances.get(index);
    }
}
